package com.icongyou.enterprise.talent_marking;

import com.icongyou.enterprise.common.result.Result;
import com.icongyou.enterprise.talent_marking.entity.vo.ChangeDetailVO;
import com.icongyou.enterprise.talent_marking.entity.vo.ChangeItemVO;
import com.icongyou.enterprise.talent_marking.service.PerformanceChangesService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class PerformanceChangesServiceTest {

    @Mock
    private PerformanceChangesService performanceChangesService;

    @Test
    void getRecentChanges_ShouldReturnChangeList() {
        // Arrange
        // 创建 ChangeItemVO 列表
        ChangeItemVO changeItem1 = new ChangeItemVO();
        changeItem1.setCourseId("COURSE001");
        changeItem1.setCourseName("数学");
        changeItem1.setChangeType("成绩提升");
        changeItem1.setChangeDescription("数学成绩从80分提升到90分");
        changeItem1.setDetectedTime(new Date());

        ChangeItemVO changeItem2 = new ChangeItemVO();
        changeItem2.setCourseId("COURSE002");
        changeItem2.setCourseName("英语");
        changeItem2.setChangeType("排名进步");
        changeItem2.setChangeDescription("班级排名从第15名进步到第10名");
        changeItem2.setDetectedTime(new Date());

        // 创建 ChangeDetailVO
        ChangeDetailVO changeDetail1 = new ChangeDetailVO();
        changeDetail1.setStudentId("STU001");
        changeDetail1.setStudentName("张三");
        changeDetail1.setChanges(Arrays.asList(changeItem1, changeItem2));
        changeDetail1.setLatestChangeTime(new Date());

        ChangeDetailVO changeDetail2 = new ChangeDetailVO();
        changeDetail2.setStudentId("STU002");
        changeDetail2.setStudentName("李四");
        changeDetail2.setChanges(Arrays.asList(changeItem1));
        changeDetail2.setLatestChangeTime(new Date());

        List<ChangeDetailVO> changes = Arrays.asList(changeDetail1, changeDetail2);
        Result<List<ChangeDetailVO>> expectedResult = Result.success(changes);

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(200, result.getCode());
        assertEquals(2, result.getData().size());

        // 验证第一个学生的数据
        ChangeDetailVO firstStudent = result.getData().get(0);
        assertEquals("STU001", firstStudent.getStudentId());
        assertEquals("张三", firstStudent.getStudentName());
        assertEquals(2, firstStudent.getChanges().size());

        // 验证第一个变化项
        ChangeItemVO firstChange = firstStudent.getChanges().get(0);
        assertEquals("COURSE001", firstChange.getCourseId());
        assertEquals("数学", firstChange.getCourseName());
        assertEquals("成绩提升", firstChange.getChangeType());
        assertEquals("数学成绩从80分提升到90分", firstChange.getChangeDescription());
        assertNotNull(firstChange.getDetectedTime());

        // 验证第二个学生的数据
        ChangeDetailVO secondStudent = result.getData().get(1);
        assertEquals("STU002", secondStudent.getStudentId());
        assertEquals("李四", secondStudent.getStudentName());
        assertEquals(1, secondStudent.getChanges().size());

        verify(performanceChangesService).getRecentChanges();
    }

    @Test
    void getRecentChanges_WhenNoChanges_ShouldReturnEmptyList() {
        // Arrange
        List<ChangeDetailVO> emptyList = Arrays.asList();
        Result<List<ChangeDetailVO>> expectedResult = Result.success(emptyList);

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(200, result.getCode());
        assertTrue(result.getData().isEmpty());

        verify(performanceChangesService).getRecentChanges();
    }

    @Test
    void getRecentChanges_WhenStudentHasNoChangeItems_ShouldHandleGracefully() {
        // Arrange
        ChangeDetailVO changeDetail = new ChangeDetailVO();
        changeDetail.setStudentId("STU003");
        changeDetail.setStudentName("王五");
        changeDetail.setChanges(Arrays.asList()); // 空的变化列表
        changeDetail.setLatestChangeTime(new Date());

        List<ChangeDetailVO> changes = Arrays.asList(changeDetail);
        Result<List<ChangeDetailVO>> expectedResult = Result.success(changes);

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(200, result.getCode());
        assertEquals(1, result.getData().size());

        ChangeDetailVO student = result.getData().get(0);
        assertEquals("STU003", student.getStudentId());
        assertTrue(student.getChanges().isEmpty());

        verify(performanceChangesService).getRecentChanges();
    }

    @Test
    void getRecentChanges_WhenServiceError_ShouldReturnError() {
        // Arrange
        Result<List<ChangeDetailVO>> expectedResult = Result.error("获取变化数据失败");

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(500, result.getCode());
        assertEquals("获取变化数据失败", result.getMessage());

        verify(performanceChangesService).getRecentChanges();
    }

    @Test
    void getRecentChanges_WithCustomErrorCode_ShouldReturnCorrectCode() {
        // Arrange
        Result<List<ChangeDetailVO>> expectedResult = Result.error(404, "未找到变化数据");

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(404, result.getCode());
        assertEquals("未找到变化数据", result.getMessage());

        verify(performanceChangesService).getRecentChanges();
    }

    @Test
    void getRecentChanges_WithMultipleChangeTypes_ShouldReturnAllTypes() {
        // Arrange
        // 创建不同类型的 ChangeItemVO
        ChangeItemVO scoreChange = new ChangeItemVO();
        scoreChange.setCourseId("COURSE001");
        scoreChange.setCourseName("数学");
        scoreChange.setChangeType("成绩提升");
        scoreChange.setChangeDescription("期末考试成绩提升10分");
        scoreChange.setDetectedTime(new Date());

        ChangeItemVO rankChange = new ChangeItemVO();
        rankChange.setCourseId("COURSE002");
        rankChange.setCourseName("英语");
        rankChange.setChangeType("排名进步");
        rankChange.setChangeDescription("班级排名进步5名");
        rankChange.setDetectedTime(new Date());

        ChangeItemVO assignmentChange = new ChangeItemVO();
        assignmentChange.setCourseId("COURSE003");
        assignmentChange.setCourseName("编程");
        assignmentChange.setChangeType("作业质量提升");
        assignmentChange.setChangeDescription("最近三次作业评分均为优秀");
        assignmentChange.setDetectedTime(new Date());

        ChangeDetailVO changeDetail = new ChangeDetailVO();
        changeDetail.setStudentId("STU004");
        changeDetail.setStudentName("赵六");
        changeDetail.setChanges(Arrays.asList(scoreChange, rankChange, assignmentChange));
        changeDetail.setLatestChangeTime(new Date());

        List<ChangeDetailVO> changes = Arrays.asList(changeDetail);
        Result<List<ChangeDetailVO>> expectedResult = Result.success(changes);

        when(performanceChangesService.getRecentChanges()).thenReturn(expectedResult);

        // Act
        Result<List<ChangeDetailVO>> result = performanceChangesService.getRecentChanges();

        // Assert
        assertNotNull(result);
        assertEquals(200, result.getCode());
        assertEquals(1, result.getData().size());

        ChangeDetailVO student = result.getData().get(0);
        assertEquals(3, student.getChanges().size());

        // 验证不同类型的变化项
        assertEquals("成绩提升", student.getChanges().get(0).getChangeType());
        assertEquals("排名进步", student.getChanges().get(1).getChangeType());
        assertEquals("作业质量提升", student.getChanges().get(2).getChangeType());

        verify(performanceChangesService).getRecentChanges();
    }
}
